
//
// 120305 - AH - Creates.
// 120306 - AH - (Huset) Finished java doc.
//

package org.soekrat.gui.swing.dictionary;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.soekrat.engine.dictionary.Dictionary;
import org.soekrat.engine.dictionary.SimpleDictionary;
import org.soekrat.gui.swing.TestFrame;

/**
 * <p>
 *   Panel with a text field that auto complete from a 
 *   {@link Dictionary} and if end user select a word from list of suggestions
 *   replaces everything in the text field with it. 
 * </p>
 * @author Arne Halvorsen (AH)
 */
@SuppressWarnings("serial")
public final class DictionaryAutoCompleteReplaceTextView extends JPanel 
{
  private transient List<ChangeListener> m_listeners=null;
  
  private final DictionaryAutoCompleteView m_dacv=
    new DictionaryAutoCompleteView();
  
  private final JTextField m_text=new JTextField();
  
  /**
   * <p>
   *   Constructor.
   * </p>
   */
  public DictionaryAutoCompleteReplaceTextView(){ this(null); }
  
  /**
   * <p>
   * </p>
   * @param dict Dictionary to use.
   */
  public DictionaryAutoCompleteReplaceTextView(Dictionary dict)
  {
    dict=(dict==null) ? new SimpleDictionary() : dict;
    
    m_dacv.setDictionary(dict);
    
    setLayout(new BorderLayout());
    
    add(m_text, BorderLayout.NORTH);
    add(m_dacv, BorderLayout.CENTER);
    
    m_text.addKeyListener
    (
      new KeyListener() 
      {  
        public void keyTyped(KeyEvent e){}
        public void keyPressed(KeyEvent e){}
        
        public void keyReleased(KeyEvent e)
        {
          String txt=m_text.getText();
          m_dacv.setPrefix(txt);
        } 
      }
    );
    
    m_text.addActionListener
    (
      new ActionListener() 
      {
        public void actionPerformed(ActionEvent e)
        {
          String txt=m_text.getText();
          txt=(txt==null) ? "" : txt.trim();
          if (txt.length()>0) fire(); 
        }
      }
    );
    
    m_dacv.addChangeListener
    (
      new ChangeListener() 
      {
        public void stateChanged(ChangeEvent e) 
        {
          String word=m_dacv.getSelected();
          if (word!=null) m_text.setText(word);     
        }
      }
    );
    
  }
  
  /**
   * <p>
   *   Gets text.
   * </p>
   * @return Text.
   */
  public String getText(){ return m_text.getText(); }
  
  /**
   * <p>
   *   Set text.
   * </p>
   * @param txt Text to set.
   */
  public void setText(String txt)
  {
    txt=(txt==null) ? "" : txt;
    m_text.setText(txt);
    m_dacv.setPrefix(txt);
  }
  
  /**
   * <p>
   *   Gets
   *   {@link Dictionary}.
   * </p>
   * @return {@link Dictionary} or {@code null} if does not have.
   */
  public Dictionary getDictionary(){ return m_dacv.getDictionary(); }
  
  /**
   * <p>
   *   Adds
   *   {@link ChangeListener}.
   * </p>
   * @param l Listener to add.
   */
  public synchronized void addChangeListener(ChangeListener l)
  {
    if (l==null)
    {
      throw new NullPointerException("l");
    }
    
    if (m_listeners==null) m_listeners=new ArrayList<ChangeListener>();
    if (!m_listeners.contains(l)) m_listeners.add(l);
  }
  
  /**
   * <p>
   *   Removes
   *   {@link ChangeListener}.
   * </p>
   * @param l Listener to remove.
   */
  public synchronized void removeChangeListener(ChangeListener l)
  {
    if (l==null)
    {
      throw new NullPointerException("l");
    }
    
    if (m_listeners==null) return;
    m_listeners.remove(l);
  }
  
  private final static ChangeListener[] E_L_A=new ChangeListener[0];
  
  private final ChangeEvent m_ce=new ChangeEvent(this);
  
  private void fire()
  {
    if (m_listeners==null) return;
    
    ChangeListener[] l=E_L_A;
    synchronized (l){ l=m_listeners.toArray(l); }
    for (ChangeListener curr : l) curr.stateChanged(m_ce);
  }
  
  public static void main(String[] args) 
  {
    DictionaryAutoCompleteReplaceTextView dactf=new DictionaryAutoCompleteReplaceTextView();
    
    Dictionary dict=dactf.getDictionary();
    
    dict.add("arne");
    dict.add("arne halvorsen");
    
    TestFrame.show(dactf);  
  }
  
}
